package com.minivision.fdiot.rate.strategy.rate.impl;

import org.ehcache.Cache;
import org.ehcache.CacheManager;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.context.annotation.Primary;
import org.springframework.stereotype.Component;

import com.minivision.fdiot.rate.cache.RateLimiterCache;
import com.minivision.fdiot.rate.config.RateLimitingProperties;
import com.minivision.fdiot.rate.strategy.rate.RateLimiter;

import javax.servlet.http.HttpServletRequest;

/**
 * 基于缓存计数实现的限流策略
 * @author hughzhao
 * @2018年3月2日
 */
@Component
@Primary
public class DefaultRateLimiter implements RateLimiter {

  private final RateLimitingProperties rateLimitingProperties;

  private final CacheManager cacheManager;

  private final Cache<String, Integer> cache;

  @Autowired
  public DefaultRateLimiter(RateLimitingProperties rateLimitingProperties,
      RateLimiterCache rateLimiterCache) {
    this.rateLimitingProperties = rateLimitingProperties;
    this.cacheManager = rateLimiterCache.getCacheManager();
    this.cache = this.cacheManager.getCache("rate", String.class, Integer.class);
  }

  @Override
  public boolean handle(HttpServletRequest request) {
    String remoteAddress = request.getRemoteAddr();
    Integer currentCount = cache.get(remoteAddress);
    if (currentCount != null) {
      cache.put(remoteAddress, ++currentCount);
      if (currentCount > rateLimitingProperties.getLimit() - 1) {
        return false;
      }
    } else {
      cache.put(remoteAddress, 0);
    }

    return true;
  }

}
